package com.mysoft.gfyx.clue.service.impl;

import com.mysoft.framework.modeling.dto.OptionItem;
import com.mysoft.framework.service.AppService;
import com.mysoft.gfyx.clue.controller.dto.Perm.GetUserAreaPermissionResponseDto;
import com.mysoft.gfyx.clue.remoteservice.RemoteAreaService;
import com.mysoft.gfyx.clue.remoteservice.RemoteProfitService;
import com.mysoft.gfyx.clue.remoteservice.dto.AreaDto;
import com.mysoft.gfyx.clue.remoteservice.dto.GetProfitProvinceDataDto;
import com.mysoft.gfyx.clue.remoteservice.dto.ProvinceAndCityConditionDto;
import com.mysoft.gfyx.clue.service.AreaOptionService;
import com.mysoft.gfyx.clue.service.DataPermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;


@Service
public class AreaOptionServiceImp extends AppService implements AreaOptionService {

    @Autowired
    private RemoteProfitService remoteProfitService;

    @Autowired
    private DataPermissionService dataPermissionService;

    @Autowired
    private RemoteAreaService remoteAreaService;

    // 获取当前登录用户的权益和权限交集,包含省\市,或者是全国
    public List<OptionItem> getProfitWithPermissionAreaData() {
        List<OptionItem> optionItemList = new ArrayList<>();

        // 权益省份
        List<String> profitProvinceList = new ArrayList<>();
        List<AreaDto> areaDtoList;

        boolean isNationwide = false;
        ProvinceAndCityConditionDto dto = new ProvinceAndCityConditionDto();

        //1.先获取用户的权益区域
        GetProfitProvinceDataDto getProfitProvinceDataDto = remoteProfitService.getProfitProvince();
        if (getProfitProvinceDataDto == null) {
            return optionItemList;
        }
        if (getProfitProvinceDataDto.getProvinceNumType().equals(RemoteProfitService.ProvinceNumType.NationWide.toString())) {
            isNationwide = true;
        } else {
            for (OptionItem item : getProfitProvinceDataDto.getProvinceList()) {
                profitProvinceList.add(item.getValue());
            }
        }

        //2.获取用户的权限区域
        GetUserAreaPermissionResponseDto userAreaPermissionDto = dataPermissionService.getUserPermissionArea();

        //3.求交集
        if (isNationwide) {

            // 全国版的权益,只需要看用户有哪些权限区域就好了
            // 如果权限区域为空或者是有全国权限,就返回全部的省和市
            if (userAreaPermissionDto == null || userAreaPermissionDto.getArea() == null || userAreaPermissionDto.getArea().size() == 0 || userAreaPermissionDto.getArea().contains("0")) {
                areaDtoList = remoteAreaService.getAll();
            } else {
                dto.setProvinceCode(userAreaPermissionDto.getArea());
                areaDtoList = remoteAreaService.getProvinceAndCity(dto);
            }

        } else {
            //省份版的权益,取权益和权限的交集
            if (userAreaPermissionDto == null || userAreaPermissionDto.getArea() == null || userAreaPermissionDto.getArea().size() == 0 || userAreaPermissionDto.getArea().contains("0")) {
                // 没有配置权限或者是有全国的权限,返回权益省份的 省+市数据
                dto.setProvinceCode(profitProvinceList);
                areaDtoList = remoteAreaService.getProvinceAndCity(dto);
            } else {
                dto.setProvinceCode(userAreaPermissionDto.getArea());
                List<AreaDto> permissionAreaDtoList = remoteAreaService.getByCodes(dto);

                // 求权益和权限的交集
                List<String> intersectionProvinceCodes = new ArrayList<>();
                HashSet<String> codeSet = new HashSet<>();
                permissionAreaDtoList.forEach(permissionAreaDto -> {
                    if (permissionAreaDto.getParentCode().equals("0")) {
                        //省份权限, 权益省份是否包含该权限的省
                        if (profitProvinceList.contains(permissionAreaDto.getItemCode())) {
                            // 有该省份的权益和权限,那么把该省份下的城市都获取出来,添加到返回结果集
                            intersectionProvinceCodes.add(permissionAreaDto.getItemCode());
                        }
                    } else {
                        //城市权限,看城市所在的省份,是否在权益省份内
                        if (profitProvinceList.contains(permissionAreaDto.getParentCode())) {
                            OptionItem item = new OptionItem();
                            item.setText(permissionAreaDto.getItemName());
                            item.setValue(permissionAreaDto.getItemCode());
                            item.setParent(permissionAreaDto.getParentCode());
                            //去个重,因为有些数据会同时包含 省和这个省下的某些市,就会导致城市数据出现重复
                            if (!codeSet.contains(item.getValue())) {
                                optionItemList.add(item);
                                codeSet.add(item.getValue());
                            }

                        }
                    }
                });

                // 取出权益和权限交集省份的所有子城市,添加到结果集中
                if (intersectionProvinceCodes.size() != 0) {
                    dto.setProvinceCode(intersectionProvinceCodes);
                    List<AreaDto> provinceAndCityList = remoteAreaService.getProvinceAndCity(dto);
                    provinceAndCityList.forEach(areaDto -> {
                        OptionItem optionItem = new OptionItem();
                        optionItem.setText(areaDto.getItemName());
                        optionItem.setValue(areaDto.getItemCode());
                        optionItem.setParent(areaDto.getParentCode());
                        if (!codeSet.contains(optionItem.getValue())) {
                            optionItemList.add(optionItem);
                            codeSet.add(optionItem.getValue());
                        }
                    });
                }
                return optionItemList;
            }
        }

        HashSet<String> codeSet = new HashSet<>();
        areaDtoList.forEach(areaDto -> {
            OptionItem item = new OptionItem();
            item.setText(areaDto.getItemName());
            item.setValue(areaDto.getItemCode());
            item.setParent(areaDto.getParentCode());
            if (!codeSet.contains(item.getValue())) {
                optionItemList.add(item);
                codeSet.add(item.getValue());
            }
        });
        return optionItemList;
    }
}
